"""
单元测试类。

进行测试，建立通信簿并进行各类操作。

0. 搜索功能

1. 添加联系人

2. 更新联系人

3. 展示所有联系人

4. 导出和导入联系人
"""
import time
import unittest

from AddressBook import AddressBook, Contact, Head


class TestAddressBook(unittest.TestCase):

    def setUp(self):
        self.data = [
            ["赵高见", "15537949663", "VJjW9hmZMx@126.com", "赵高见.jpg", "200", "200"],
            ["钱已特", "15878036147", "jHqxgXX@189.com", "钱已特.jpg", "200", "200"],
            ["陈理特", "18589243815", "P1APGTfdv6@126.com", "陈理特.jpg", "200", "200"],
            ["褚感几", "18564479973", "iOMptJq@163.com", "褚感几.jpg", "200", "200"],
            ["郑点", "17230047469", "wxPpHyhOp@126.com", "郑点.jpg", "200", "200"],
        ]
        self.cs = []
        for line in self.data[0:-1]:
            self.cs.append(Contact(line[0], line[1], line[2], Head(line[-3], int(line[-2]), int(line[-1]))))
        self.ab = AddressBook(*self.cs)

    def test_search(self):
        """
        搜索功能单元测试：
            1.搜索已在的Tel，返回对应联系人

            2.搜索已在的Email，返回对应联系人

            3.搜索不在的Tel，返回空列表

            4.搜索不在的Email，返回空列表
        """
        lines = self.data[2:]
        search_result = [self.ab.search(i, j)
                         for i, j in
                         [("tel", lines[0][1]), ("email", lines[1][2]), ("tel", lines[2][0]), ("email", lines[2][1])]]
        self.assertEqual(search_result[0][0].get_tel(), lines[0][1])
        self.assertEqual(search_result[1][0].get_email(), lines[1][2])
        self.assertEqual(search_result[2], [])
        self.assertEqual(search_result[3], [])

    def test_add(self):
        """
        联系人添加功能单元测试：
            1.没有的联系人应当正常添加，创建时间=更新时间

            2.电话或邮箱存在的联系人应当抛出添加异常
        """
        line3, line4 = self.data[3:]

        self.ab.add(line4[0], line4[1], line4[2], Head(line4[-3], int(line4[-2]), int(line4[-1])))
        self.assertEqual(str(self.ab.records[-1][0]), "Name: {}\tTel: {}\tEmail: {}\tHead: {}_{}_{}".format(*line4))
        self.assertEqual(self.ab.records[-1][1], self.ab.records[-1][2])

        n0 = self.ab.get_records_num()
        self.ab.add(line3[0], line3[1], line3[2], Head(line3[-3], int(line3[-2]), int(line3[-1])))
        n1 = self.ab.get_records_num()
        self.assertEqual(n0, n1)

    def test_update_1(self):
        """
        更新联系人 1
            1.联系人已存在且新信息无冲突应当正常更新，信息更新且更新时间变化
        """
        params = [
            ["tel", "15537949663", "18813018834"],
            ["email", "jHqxgXX@189.com", "10001@qq.com"]
        ]
        a = self.ab
        t1 = a.last_update
        time.sleep(1)
        a.update(params[0][0], params[0][1], params[0][2])
        self.assertNotEqual(t1, a.last_update)
        t2 = a.last_update
        time.sleep(1)
        a.update(params[1][0], params[1][1], params[1][2])
        self.assertNotEqual(t2, a.last_update)

    def test_update_2(self):
        """
        更新联系人 2
            2.电话信息没有的应当阻止更新，信息不变

            3.新的电话信息有冲突应当阻止更新，信息不变

            4.邮箱信息没有的应当阻止更新，信息不变

            5.新的邮箱信息有冲突应当阻止更新，信息不变
        """
        params = [
            ["tel", "18813018834", "11111"],
            ["tel", "15537949663", "15878036147"],
            ["email", "10001@qq.com", "3344@126.com"],
            ["email", "jHqxgXX@189.com", "iOMptJq@163.com"]
        ]
        a = self.ab
        t = a.last_update
        a.update(params[0][0], params[0][1], params[0][2])
        self.assertEqual(t, a.last_update)
        a.update(params[1][0], params[1][1], params[1][2])
        self.assertEqual(t, a.last_update)
        a.update(params[2][0], params[2][1], params[2][2])
        self.assertEqual(t, a.last_update)
        a.update(params[3][0], params[3][1], params[3][2])
        self.assertEqual(t, a.last_update)

    def test_show(self):
        """
        打印所有联系人信息，保证排序正确。
        """
        rule_list = ["default", "name", "tel", "email", "pinyin"]
        for rule in rule_list:
            print(f"Rule: {rule}\n")
            self.ab.show(rule)
            print("\n")
            self.ab.show(rule, reverse=True)
            print("\n\n")

    def test_save_load(self):
        """
        测试通讯簿导入导出功能。
            应当保证联系人信息，创建、更改时间在导入导出前后无变化。
        """
        ab0 = self.ab
        ab_path = ab0.save("./")
        ab1 = AddressBook()
        ab1.load(ab_path)
        for i in range(ab0.get_records_num()):
            self.assertEqual(str(ab0.records[i][0]), str(ab1.records[i][0]))
            self.assertEqual(ab0.records[i][1], ab1.records[i][1])
            self.assertEqual(ab0.records[i][2], ab1.records[i][2])


if __name__ == '__main__':
    unittest.main()

"""
本测试注意：
    1. 联系人更新时，速度太快以至于难以测试时间差，故人为睡眠一秒
    2. 展示联系人时，如何判定排序成功需靠肉眼观察
"""
